﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ServiceModel;
using System.Data.Services.Client;
using System.Threading;

namespace Buggy
{
    public class BuggyManager
    {
        public DataServiceCollection<BuggyDataService.Categories> categories { get; private set; }
        public DataServiceCollection<BuggyDataService.Bugs> bugs { get; private set; }
        public DataServiceCollection<BuggyDataService.BugComments> bugComments { get; private set; }

        public BuggyManager()
        {
            categories = new DataServiceCollection<BuggyDataService.Categories>();
            bugs = new DataServiceCollection<BuggyDataService.Bugs>();
            bugComments = new DataServiceCollection<BuggyDataService.BugComments>();
        }

        public void LoadCategories(SendOrPostCallback callback)
        {
            categories.LoadCompleted += (object sender, LoadCompletedEventArgs e) => {
                if (e.Error == null)
                    SynchronizationContext.Current.Send(callback, categories);
            };
            categories.LoadAsync(BuggyWebServices.dataService.Categories.AsQueryable());
        }

        public void CreateBug(int categoryId, string name, string description, SendOrPostCallback callback)
        {
            if (callback != null)
            {
                BuggyWebServices.manageService.CreateBugCompleted += (object sender, BuggyService.CreateBugCompletedEventArgs e) =>
                {
                    SynchronizationContext.Current.Send(callback, e.Result);
                };
            }
            BuggyWebServices.manageService.CreateBugAsync(categoryId, name, description);
        }

        public void GetRelatedUsersByBug(int bugid, SendOrPostCallback callback)
        {
            if (callback != null)
            {
                BuggyWebServices.manageService.GetRelatedUsersByBugCompleted += (object sender, BuggyService.GetRelatedUsersByBugCompletedEventArgs e) =>
                {
                    SynchronizationContext.Current.Send(callback, e);
                };
            }
            BuggyWebServices.manageService.GetRelatedUsersByBugAsync(bugid);
        }

        public void AddUserToBug(string username, int bugid, SendOrPostCallback callback)
        {
            if (callback != null)
            {
                BuggyWebServices.manageService.AddUserToBugCompleted += (object sender, System.ComponentModel.AsyncCompletedEventArgs e) =>
                {
                    SynchronizationContext.Current.Send(callback, e);
                };
            }
            BuggyWebServices.manageService.AddUserToBugAsync(username, bugid);
        }

        public void RemoveUserFromBug(string username, int bugid, SendOrPostCallback callback)
        {
            if (callback != null)
            {
                BuggyWebServices.manageService.RemoveUserFromBugCompleted += (object sender, System.ComponentModel.AsyncCompletedEventArgs e) =>
                {
                    SynchronizationContext.Current.Send(callback, e);
                };
            }
            BuggyWebServices.manageService.RemoveUserFromBugAsync(username, bugid);
        }

        public void LoadBugs(int categoryId, SendOrPostCallback callback)
        {
            if (callback != null)
            {
                bugs.LoadCompleted += (object sender, LoadCompletedEventArgs e) => {
                    if (e.Error == null)
                        SynchronizationContext.Current.Send(callback, bugs);
                };
            }

            var query = from b in BuggyWebServices.dataService.Bugs 
                        where b.categoryId == categoryId 
                        select b;
            bugs.Clear();
            bugComments.Clear();
            bugs.LoadAsync(query);
        }

        public void LoadBugComments(int bugId, SendOrPostCallback callback)
        {
            if (callback != null)
            {
                bugComments.LoadCompleted += (object sender, LoadCompletedEventArgs e) => {
                    if (e.Error == null)
                        SynchronizationContext.Current.Send(callback, bugComments);
                };
            }

            var query = from bc in BuggyWebServices.dataService.BugComments 
                        where bc.bugId == bugId 
                        select bc;
            bugComments.Clear();
            bugComments.LoadAsync(query);
        }

        public void AddBugComment(int bugid, string comment, SendOrPostCallback callback)
        {
            BuggyDataService.BugComments bc = new BuggyDataService.BugComments();
            bc.bugId = bugid;
            bc.content = comment;
            bc.date = DateTime.Now;

            BuggyWebServices.dataService.AddToBugComments(bc);
            BuggyWebServices.dataService.BeginSaveChanges((IAsyncResult ar) => 
            { 
                var resp = BuggyWebServices.dataService.EndSaveChanges(ar);
                if (callback != null)
                    SynchronizationContext.Current.Send(callback, bc);
            }, null);
        }

        public void ChangeBugComment(BuggyDataService.BugComments bc, string comment, SendOrPostCallback callback)
        {
            bc.content = comment;
            BuggyWebServices.dataService.UpdateObject(bc);
            BuggyWebServices.dataService.BeginSaveChanges((IAsyncResult ar) => 
            { 
                var resp = BuggyWebServices.dataService.EndSaveChanges(ar); 
            }, null);
        }

        public void ChangeBugName(BuggyDataService.Bugs bug, string newname, SendOrPostCallback callback)
        {
            var oldValue = bug.name;
            bug.name = newname;
            BuggyWebServices.dataService.UpdateObject(bug);
            BuggyWebServices.dataService.BeginSaveChanges((IAsyncResult ar) =>
            {
                try
                {
                    BuggyWebServices.dataService.EndSaveChanges(ar);
                    if (callback != null)
                        SynchronizationContext.Current.Send(callback, bug);
                }
                catch (DataServiceRequestException ex)
                {
                    MessageBox.Show(ex.Message);
                    bug.name = oldValue;
                }
            }, null);
        }

        public void ChangeBugDescription(BuggyDataService.Bugs bug, string newdescription, SendOrPostCallback callback)
        {
            var oldValue = bug.description;
            bug.description = newdescription;
            BuggyWebServices.dataService.UpdateObject(bug);
            BuggyWebServices.dataService.BeginSaveChanges((IAsyncResult ar) =>
            {
                try
                {
                    BuggyWebServices.dataService.EndSaveChanges(ar);
                    if (callback != null)
                        SynchronizationContext.Current.Send(callback, bug);
                }
                catch (DataServiceRequestException ex)
                {
                    MessageBox.Show(ex.Message);
                    bug.description = oldValue;
                }
            }, null);
        }

        public void Login(string login, string password, SendOrPostCallback callback)
        {
            if (callback != null)
            {
                BuggyWebServices.manageService.LoginCompleted += (object sender, BuggyService.LoginCompletedEventArgs e) => 
                {
                    SynchronizationContext.Current.Send(callback, e.Result);
                };
            }
            BuggyWebServices.manageService.LoginAsync(login, password);
        }

        public void Logout(SendOrPostCallback callback)
        {
            if (callback != null)
            {
                BuggyWebServices.manageService.LogoutCompleted += (object sender, BuggyService.LogoutCompletedEventArgs e) =>
                {
                    SynchronizationContext.Current.Send(callback, e.Result);
                };
            }
            BuggyWebServices.manageService.LogoutAsync();
        }
    }
    
    /*
    public class UISelectionInfo
    {
        public int? selected_category_id = null;
        public int? selected_bug_id = null;
        public int? selected_bugComment_id = null;
    }
    */
    
    public class BuggyWebServices
    {
        public static readonly BuggyDataService.BuggyDataEntities dataService =
            new BuggyDataService.BuggyDataEntities(new Uri("/BuggyDataService.svc", UriKind.Relative));

        public static readonly BuggyService.BuggyServiceClient manageService =
            new BuggyService.BuggyServiceClient(new BasicHttpBinding(),
                new EndpointAddress(new Uri("/BuggyService.svc", UriKind.Relative)));        
    }
}
